//SQLite是进程内的轻量级数据库，很常用接口：sqlite3_threadsafe() 查看当前数据库在编译阶段是否启动了线程安全；返回1表示线程安全
//sqlite有三种线程安全等级，一是非线程安全模式，二是线程安全模式，三是串行化模式
//sqlite3_open 创建、打开数据库文件，并返回操作句柄
//int sqlite3_open(const char* filename , sqlite** ppdb) 
//sqlite3_open_v2 为在程序运行期间通过参数选择线程安全等级，SQLITE_OPEN_READWEITE 以可读可写方式打开数据库 返回值为SQLITE_OK表示运行成功
//SQLITE_OPEN_CREATE B不存在数据库文件便创建，SQLITE_OPEN_NOMUTEX 多线程模式，只要不同的线程使用不同的连接即可保证线程安全
//SQLITE_OPEN_FULLMUTEX 串行化模式
//执行语句:sqlite3_exec ，传入句柄、sql语句、回调函数、参数、出错；其中回调函数有int返回值，返回0表示运行成功，返回非0会触发ABORT使得程序退出
//返回SQLITE_OK表示函数运行成功
#include"sqlite.hpp"
#include<cassert>

//设置回调函数
// typedef int(*SqliteCallback)(void*,int,char**,char**);参数 列数 回调函数 查询结果 字段名称
int select_stu_callback(void* args , int col_count , char** result , char** fileds_name)
{
    //让args将结果result 带出去
    std::vector<std::string> *array = (std::vector<std::string>*) args;//先强转类型
    array->push_back(result[0]);//由于只查询了一列，result 实则是一个字符指针数组，每一个元素指向一列的数据
    return 0;//此处必须要返回0，不然就会调用ABORT结束进程
}

int main()
{
    //创建or打开数据库
    SqliteHelper helper("./test.db");
    assert(helper.open());
    //操作
    const char* ct = "create table if not exists student(sn int primary key, name varchar(20) , age int);";
    assert(helper.exec(ct , nullptr, nullptr));//基于sql语句查询结果的的才用的上sqlite3_exec 中的回调函数与参数
    //插入数据
    // const char* insert_sql = "insert into student values(1, '张三' ,20),(2,'李四' ,16) ,(3,'王五',17);";
    // assert(helper.exec(insert_sql, nullptr , nullptr));
    //修改数据
    // const char* update_sql = "update student set name='张333' where sn=1;";
    // assert(helper.exec(update_sql, nullptr , nullptr));
    // //删除数据
    // const char*delete_sql = "delete from student where sn=2;";
    // assert(helper.exec(delete_sql, nullptr , nullptr));

    //使用select ，对于sqlite3_exec来说就需要用到回调函数
    const char* select_sql = "select name from student;";
    std::vector<std::string> array;
    assert(helper.exec(select_sql , select_stu_callback , &array));
    //打印array中的数据
    for(auto& e: array) std::cout << e <<std::endl;
    
    //关闭数据库
    helper.close();

    return 0;
}
